package com.qfedu.buy.server.core.wxpay;

import com.qfedu.buy.server.util.HttpUtil;
import com.qfedu.buy.server.util.XmlUtil;

import java.security.MessageDigest;
import java.util.Map;
import java.util.TreeMap;
import java.util.UUID;

/**
 * @program: NeighborBuy
 * @description:
 * @author: Feri(邢朋辉)
 * @create: 2021-02-01 09:25
 */
public class WxPayUtil {
    //微信支付账号信息
    //秘钥信息  公司提供
    private static final String APPID="wx632c8f211f8122c6";
    private static final String MCHID="1497984412";
    private static final String APPKEY="sbNCm1JnevqI36LrEaxFwcaT0hkGxFnC";

    //微信支付接口地址
    private static final String WXPAY_PAYURL="https://api.mch.weixin.qq.com/pay/unifiedorder";
    private static final String WXPAY_QUERYURL="https://api.mch.weixin.qq.com/pay/orderquery";
    private static final String WXPAY_CLOSEURL="https://api.mch.weixin.qq.com/pay/closeorder";
    private static final String WXPAY_BILLURL="https://api.mch.weixin.qq.com/pay/downloadbill";

    private static final String WXPAY_NOTIFYURL="http://locallhost:/9093/pay/wxpay/notify.do";






    /**
     * 生成签名
     * @param map 需要生成签名的参数集合要求，排过序的集合
     * @return 签名结果
     */
    public static String createSign(Map<String,String> map){
        StringBuffer buffer=new StringBuffer();
        for(String s:map.keySet()){
            buffer.append(s+"="+map.get(s)+"&");
        }
        //追加密钥
        buffer.append("key="+APPKEY);
        try {
            return createMD5(buffer.toString()).toUpperCase();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
    /**
     * 生成 MD5
     *
     * @param data 待处理数据
     * @return MD5结果
     */
    private static String createMD5(String data) throws Exception {
        MessageDigest md = MessageDigest.getInstance("MD5");
        byte[] array = md.digest(data.getBytes("UTF-8"));
        StringBuilder sb = new StringBuilder();
        for (byte item : array) {
            sb.append(Integer.toHexString((item & 0xFF) | 0x100).substring(1, 3));
        }
        return sb.toString().toUpperCase();
    }

    /**
     * 随机字符串的生成 不能超过32位*/
    public static String createRandomStr(){
        return UUID.randomUUID().toString().replaceAll("-","");
    }
    //封装微信支付操作
    /**
     * 生成预支付链接*/
    public static String createPay(WxPay pay){
        //1.组装请求参数  排序
        TreeMap<String,String> requestParams=new TreeMap<>();
        //必须的参数
        requestParams.put("appid",APPID);
        requestParams.put("mch_id",MCHID);
        requestParams.put("nonce_str",createRandomStr());
        requestParams.put("body",pay.getBody());
        requestParams.put("out_trade_no",pay.getOut_trade_no());
        requestParams.put("total_fee",pay.getTotal_fee()+"");
        requestParams.put("spbill_create_ip",pay.getIp());
        requestParams.put("notify_url",WXPAY_NOTIFYURL);
        requestParams.put("trade_type","NATIVE");
        //最后生成签名,并设置
        requestParams.put("sign",createSign(requestParams));
        //2.生成请求参数的xml字符串
        String requestXml= XmlUtil.createXml(requestParams);
        //3.请求预支付接口 统一下单接口
        String responseXml=HttpUtil.post(WXPAY_PAYURL,requestXml);
        //4.解析xml
        Map<String,String> response=XmlUtil.parseXml(responseXml);
        //5.返回预支付链接
        return response.get("code_url");
    }
    /**
     * 查询订单的支付状态
     * SUCCESS--支付成功
     * REFUND--转入退款
     * NOTPAY--未支付
     * CLOSED--已关闭
     * REVOKED--已撤销(刷卡支付)
     * USERPAYING--用户支付中
     * PAYERROR--支付失败(其他原因，如银行返回失败)
     * ACCEPT--已接收，等待扣款*/
    public static String queryPay(String oid){
        //1.组装请求参数  排序
        TreeMap<String,String> requestParams=new TreeMap<>();
        //必须的参数
        requestParams.put("appid",APPID);
        requestParams.put("mch_id",MCHID);
        requestParams.put("nonce_str",createRandomStr());
        requestParams.put("out_trade_no",oid);
        //生成签名并赋值
        requestParams.put("sign",createSign(requestParams));
        //2.生成请求参数的xml字符串
        String requestXml= XmlUtil.createXml(requestParams);
        //3.请求查询接口
        String responseXml=HttpUtil.post(WXPAY_QUERYURL,requestXml);
        //4.解析xml
        Map<String,String> response=XmlUtil.parseXml(responseXml);
        //5.返回支付状态
        return response.get("trade_state");
    }
    /**
     * 关闭订单（订单未支付）*/
    public static boolean closePay(String oid){
        //1.组装请求参数  排序
        TreeMap<String,String> requestParams=new TreeMap<>();
        //必须的参数
        requestParams.put("appid",APPID);
        requestParams.put("mch_id",MCHID);
        requestParams.put("nonce_str",createRandomStr());
        requestParams.put("out_trade_no",oid);
        //生成签名并赋值
        requestParams.put("sign",createSign(requestParams));
        //2.生成请求参数的xml字符串
        String requestXml= XmlUtil.createXml(requestParams);
        //3.请求查询接口
        String responseXml=HttpUtil.post(WXPAY_CLOSEURL,requestXml);
        //4.解析xml
        Map<String,String> response=XmlUtil.parseXml(responseXml);
        //5.返回结果
        return response.get("result_code").equals("SUCCESS");
    }


}
